package com.lotso.web;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;


/**
 * ClassName: GeneratorCodeHandler
 * Description: 自动代码生成工具
 * https://baomidou.gitee.io/mybatis-plus-doc/#/generate-code
 * Date: 2018/9/10 10:03 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class GeneratorCodeHandler {

    /**
     * 数据库参数
     */
    private DbType datasource_type = DbType.MYSQL;
    private String datasource_url = "jdbc:mysql://127.0.0.1:3306/lotso-web";
    private String datasource_userName = "root";
    private String datasource_pwd = "root";
    private String datasource_driverName = "com.mysql.jdbc.Driver";

    /**
     * 代码注释：用户
     */
    private String author = "Sam Sho";
    /**
     * 代码生成路径：需要自己定义路径
     * 完整路径应该是 codeOutputDir + package + module
     */
    private String codeOutputDir = "G:\\WorkSpace\\Sam\\Mos\\lotso-web\\src\\main\\java";
    /**
     * Mapper 文件生成路径：需要自己定义路径
     * 完整路径：mapperOutputDir + module
     */
    private String mapperOutputDir = "G:\\WorkSpace\\Sam\\Mos\\lotso-web\\src\\main\\resources\\mapper\\";

    /**
     * Entity 父类
     */
    private String superEntityClass = "com.lotso.web.module.base.AbstractDataEntity";

    /**
     * Entity 公共属性
     */
    private String[] superEntityColumns = {"id", "createDate", "updateDate"};
    /**
     * Mapper 父类
     */
    private String superMapperClass = "com.lotso.web.module.base.IBaseMapper";

    /**
     * Controller 父类
     */
    private String superControllerClass = "com.lotso.web.module.base.AbstractController";

    /**
     * 代码生成建议自定义@Test 测试
     */
    @Test
    public void generateOrgCode() {
        String packageName = "com.lotso.web.module";
        generateByTables(true, packageName, "org", "t_org_", "t_org_office", "t_org_area");
    }

    @Test
    public void generateSysCode() {
        String packageName = "com.lotso.web.module";
        generateByTables(true, packageName, "sys", "t_sys_", "t_sys_user");
    }

    @Test
    public void generateXXXCode() {
    }

    /**
     * 生成工具方法
     *
     * @param fileOverride 文件覆盖
     * @param packageName  包名
     * @param moduleName   模块名称
     * @param tablePrefix  表前缀
     * @param tableNames   表名
     */
    private void generateByTables(boolean fileOverride, String packageName, String moduleName, String tablePrefix, String... tableNames) {
        // 全局配置
        GlobalConfig config = new GlobalConfig().setActiveRecord(false)
                .setAuthor(author)
                .setOutputDir(codeOutputDir) // 输出路径
                .setFileOverride(fileOverride)
                .setEnableCache(false) // XML 二级缓存
                .setBaseResultMap(true) // XML ResultMap
                .setBaseColumnList(true) // XML columList
                .setMapperName("I%s" + ConstVal.MAPPER); // 自定义文件命名，注意 %s 会自动填充表实体属性！


        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig()
                .setDbType(datasource_type)
                .setUrl(datasource_url)
                .setUsername(datasource_userName)
                .setPassword(datasource_pwd)
                .setDriverName(datasource_driverName);

        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig()
                .setCapitalMode(true) // 全局大写命名 ORACLE 注意
                .setEntityLombokModel(true)
                .setDbColumnUnderline(true)
                .setNaming(NamingStrategy.underline_to_camel) // 表名生成策略
                .setTablePrefix(tablePrefix) // 表命名前缀
                .setInclude(tableNames) //修改替换成你需要的表名，多个表名传数组
                .setSuperEntityClass(superEntityClass) // 自定义实体父类
                .setSuperEntityColumns(superEntityColumns) // 自定义实体，公共字段
                .setSuperMapperClass(superMapperClass) // 自定义 mapper 父类
                .setSuperControllerClass(superControllerClass); //自定义 controller 父类

        // 包配置
        PackageConfig packageConfig = new PackageConfig()
                .setParent(packageName)
                .setModuleName(moduleName)
                .setController("controller")
                .setEntity("entity");

        // 自定义配置
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
            }
        };
        // 调整 xml 生成目录演示
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/gen/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return mapperOutputDir + moduleName + "\\" + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        injectionConfig.setFileOutConfigList(focList);

        // 模板配置：注意不需要加ftl后缀
        TemplateConfig tc = new TemplateConfig()
                .setController("/templates/gen/controller.java")
                .setService("/templates/gen/service.java")
                .setServiceImpl("/templates/gen/serviceImpl.java")
                .setEntity("/templates/gen/entity.java")
                .setMapper("/templates/gen/mapper.java")
                .setXml(null);// 关闭默认 xml 生成，调整生成至自定义

        // 自动集成
        new AutoGenerator()
                .setTemplateEngine(new FreemarkerTemplateEngine())
                .setCfg(injectionConfig)
                .setTemplate(tc)
                .setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .execute();
    }
}